import { ANY_DATA_TYPE } from '@/type'
interface LinkedParam {
  len: number
  // ... other properties
}
interface LinkedBaseInterFace {
  pre: unknown
  next: unknown
  index: number
  len: number
}
export class LinkedBase implements LinkedBaseInterFace {
  pre: LinkedBase | null = null
  next: LinkedBase | null = null
  index = 0
  len = 0
  constructor (param: LinkedParam = { len: 1 }) {
    const { len } = param
    this.len = len
  }
}

export class LinkedList extends LinkedBase {
  constructor (param: LinkedParam = { len: 1 }) {
    super(param)
    const { len } = param
    if (len > 1) {
      let temp: LinkedList | null = null
      let next = null
      this.len = len
      for (let i = 1; i < len; i++) {
        next = new LinkedList()
        next.index = i
        next.len = len
        if (i === 1) {
          this.next = next
          next.pre = this
        } else {
          if (temp) {
            temp.next = next
          }
          if (next) {
            next.pre = temp
          }
        }
        temp = next
      }
      this.pre = next
    }
  }
}
export class OneWayLinkedList extends LinkedBase {
  next: OneWayLinkedList | null = null
  constructor (param = { len: 1 }) {
    super(param)
    const { len } = param
    if (len > 1) {
      let next = null
      let temp: OneWayLinkedList | null = null
      for (let i = 1; i < len; i++) {
        next = new OneWayLinkedList()
        if (i === 1) {
          this.next = next
          next.index = i
          temp = next
        } else {
          if (temp) {
            temp.next = next
            temp.next.index = i
            temp = temp.next
          }
          if (i === len - 1) {
            if (temp) {
              temp.next = this
            }
          }
        }
      }
    }
  }
}
export class DoubleWayLinkedList extends LinkedBase {
  constructor (param = { len: 1 }) {
    super(param)
    const { len } = param
    if (len > 1) {
      let temp = null
      let next = null
      for (let i = 1; i < len; i++) {
        next = new DoubleWayLinkedList()
        next.len = len
        if (i === 1) {
          this.next = next
          next.index = i
          next.pre = this
          temp = next
        } else {
          if (temp) {
            temp.next = next
            temp.next.len = len
            temp.next.pre = temp
            temp.next.index = i
            temp = temp.next
          }
        }
      }
    }
  }
}
export class CircularLinkedList extends LinkedBase {
  constructor (param = { len: 1 }) {
    super(param)
    const { len } = param
    if (len > 1) {
      let temp: CircularLinkedList | null = null
      let next = null
      for (let i = 1; i < len; i++) {
        next = new CircularLinkedList()
        next.len = len
        if (i === 1) {
          this.next = next
          next.index = i
          next.pre = this
          temp = next
        } else {
          if (temp && next) {
            temp.next = next
            temp.next.pre = temp
            temp.next.index = i
            temp = temp.next
          }
          if (i === len - 1) {
            if (temp) {
              temp.next = this
            }
          }
        }
      }
    }
  }
}
export const toLinkedList = (eample: ANY_DATA_TYPE) => {
  const result = [eample]
  const len = eample.len
  let index = 1
  if (len === 1) {
    return result
  }
  let next = eample.next
  while (index < len) {
    result.push(next)
    next = next.next
    index += 1
  }
  return result
}
